/**
 * Copyright 2014 wasu.com
 *
 *
 * Create on 2014-12-29 下午4:30:21
 */
package xiaojian.toolkit.jms;

import java.io.UnsupportedEncodingException;
import java.util.UUID;

import org.apache.commons.collections4.Transformer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import xiaojian.toolkit.bean.json.JSONSignal;
import xiaojian.toolkit.bean.json.annotation.JSONMessage;
import xiaojian.toolkit.bean.utils.CodecUtils;
import xiaojian.toolkit.util.MutableIdentifyable;

import com.alibaba.fastjson.JSON;
import com.google.common.primitives.Bytes;

/**
 * 将需要传输的对象转换为byte的数组。
 * 
 * @author <a href="mailto:caoxiaojian@wasu.com>xiaojian.cao</a>
 * 
 */
public class Msg2BytesTransformer implements Transformer<JSONSignal, byte[]> {

	private static final Logger logger = LoggerFactory
			.getLogger(Msg2BytesTransformer.class);

	private CodecUtils tlvEncoder;

	/**
	 * @see stc.skymobi.util.Transformer#transform(java.lang.Object)
	 */
	@Override
	public byte[] transform(JSONSignal msg) {
		JSONMessage jm = msg.getClass().getAnnotation(JSONMessage.class);
		if (jm == null) {
			throw new RuntimeException(
					"invalid json message, missing @JSONMessage.");
		}

		final UUID id = ((MutableIdentifyable) msg).getIdentification();
		if (logger.isDebugEnabled()) {
			logger.debug("encoding JSONObject {} to wrappedBuffer", msg);
		}
		if (null != id) {
			final String jsonString = JSON.toJSONString(msg);
			byte[] jsonBytes = null;
			try {
				jsonBytes = jsonString.getBytes("UTF-8");
			} catch (UnsupportedEncodingException e) {
				logger.error("Unsupport encoding['utf-8'].", e);
				return null;
			}
			return Bytes.concat(
					this.tlvEncoder.genHeaderToBytes((byte) 100, id,
							jm.messageCode(), jsonBytes.length), jsonBytes);
		} else {
			if (logger.isWarnEnabled()) {
				logger.warn("{} is json but missing transactionId", msg);
			}
		}

		return null;
	}

	/**
	 * @return the tlvEncoder
	 */
	public CodecUtils getTlvEncoder() {
		return tlvEncoder;
	}

	/**
	 * @param tlvEncoder
	 *            the tlvEncoder to set
	 */
	public void setTlvEncoder(CodecUtils tlvEncoder) {
		this.tlvEncoder = tlvEncoder;
	}

}
